package online.zhangwenzhe.common.security.Impl;

import online.zhangwenzhe.common.security.AuthorityVerifier;
import online.zhangwenzhe.common.security.datasource.AuthenticationService;
import online.zhangwenzhe.common.security.datasource.ResourceRoleMapVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.util.ArrayList;
import java.util.List;

/**
 * 说明：
 *
 * @author 张文哲
 * @version 1.0.0
 * @since 2018/7/3 16:23
 */

@Component
public class AuthorityVerifierImpl implements AuthorityVerifier {
    @Autowired
    AuthenticationService authenticationService;

    @Override
    public boolean verify(String username, String uri, String httpMethod) {

        List<ResourceRoleMapVo> resourceRoleMapVoList = authenticationService.getResourceRoleMap();
        List<String> rolesCanAccess = new ArrayList<>();

        PathMatcher urlMatcher = new AntPathMatcher();
        // 寻找可以访问此资源的全部角色(因为有可能父目录通配符授权)
        resourceRoleMapVoList.forEach(x -> {
            if (urlMatcher.match(x.getUri(), uri)
                    && httpMethod.equals(x.getMethod())) {
                rolesCanAccess.addAll(x.getRoleIdList());
            }
        });


        //矛盾：如果允许匿名访问，那就和通配符冲突，因为任何一个资源，肯定可以被/**这个匹配，就无法识别匿名了
        //无需授权资源直接通过
        if (rolesCanAccess.size() == 0) {
            return false;
        }

        //匿名用户直接拒绝
        if ("anonymousUser".equals(username)) {
            return false;
        }

        List<String> rolesOwned = authenticationService.getRoleByUser(Long.valueOf(username));

        for (String needRole : rolesCanAccess) {
            if (rolesOwned.contains(needRole)) {
                return true;
            }
        }

        return false;
    }
}
